-- FormEffectM
-- create by zouyb
-- 窗口效果

module("FormEffectM", package.seeall);

-- 出现特效

-- 慢慢从中间出来
FORM_EFFECT_COME_FROM_CENTER        = "come_from_center";
-- 从上面掉下来
FORM_EFFECT_DROP_DOWN               = "drop_down";
-- 左右飞入
FORM_EFFECT_LEFT_RIGHT_FLY_IN       = "left_right_fly_in";
-- 阶梯飞入
FORM_EFFECT_DIF_LEFT_RIGHT_FLY_IN   = "dif_left_right_fly_in";
-- 特殊处理的
FORM_EFFECT_SPECIAL_IN              = "special_in";


-- 消失特效

-- 从中心点消失
FORM_EFFECT_GONE_FROM_CENTER        = "gone_from_center";
-- 缩回到上面
FORM_EFFECT_TOP_UP                  = "lift_up";
-- 左右飞出
FORM_EFFECT_LEFT_RIGHT_FLY_OUT      = "left_right_fly_out";

-- 窗口特效配置
local formEffectConfig = {};

-- 加载配置文件
function init()
    -- 转换下audio信息表
    local form_effect_CSV = get_form_effect_CSV();
    for i = 1, #form_effect_CSV do
        formEffectConfig[form_effect_CSV[i].form_name] = form_effect_CSV[i];
    end
end

-- 根据窗口名称查询窗口特效
function query(name, path)
    local m = formEffectConfig[name];

    if not m or path == "" or not path then
        return nil;
    end

    return m[path];
end

-- 设置出现的特效
function setAppearEffect(form, effectName)
    form.appearEffectName = effectName;
end

-- 设置消失的特效
function setDisappearEffect(form, effectName)
    form.disappearEffectName = effectName;
end

-- 运行出现特效
function runAppearEffect(form)
    if form.appearEffectName == FORM_EFFECT_COME_FROM_CENTER then
        -- CT从中心弹出
        ctPopUpFromCenter(form);

        -- BT节点一段时间后，从底部往上弹出
        btPopUpFromBottom(form);
    elseif form.appearEffectName == FORM_EFFECT_DROP_DOWN then
        -- CT从上面掉下来
        ctDropDown(form);

        -- BT节点一段时间后，从底部往上弹出
        btPopUpFromBottom(form);
    elseif form.appearEffectName == FORM_EFFECT_LEFT_RIGHT_FLY_IN then
        -- CT从右边飞入
        ctFlyInFromRight(form);

        -- BT从左右飞入
        btFlyInFromLeft(form);
    elseif form.appearEffectName == FORM_EFFECT_DIF_LEFT_RIGHT_FLY_IN then
        -- CT从右边飞入
        ctFlyInFromRight(form);

        -- BOTTOM/BT阶梯从左飞入
        btFlyInFromLeftDif(form)
    elseif form.appearEffectName == FORM_EFFECT_SPECIAL_IN then
        -- 特殊化效果此处不处理
    else
        -- 默认的效果，BT节点一段时间后，从底部往上弹出
        btPopUpFromBottom(form);
    end
end

-- 运行消失特效
function runDisppearEffect(form, callback)
    form.disappearCallFunc = cc.CallFunc:create(callback);
    if form.disappearEffectName == FORM_EFFECT_LIFT_UP then
        -- CT节点往上收
        ctMoveUp(form);

        -- BT往下收
        btMoveDown(form);

        -- bg渐隐
        bgFadeOut(form);
    elseif form.disappearEffectName == FORM_EFFECT_GONE_FROM_CENTER then
        -- CT快速放大并渐隐
        ctScaleUpAndHide(form);

        -- BT往下收
        btMoveDown(form);

        -- bg渐隐
        bgFadeOut(form);
    elseif form.disappearEffectName == FORM_EFFECT_LEFT_RIGHT_FLY_OUT then
        -- CT从右边飞出
        ctFlyOutFromRight(form);

        -- BT从左右飞出
        btFlyOutFromLeft(form);
    else
        callback();
    end
end


-- CT从上面掉下来
function ctDropDown(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldPos = cc.p(CT:getPosition());

    -- CT节点从上面往下掉，并略微回弹下
    CT:setPosition(oldPos.x, DESIGN_HEIGHT);
    local moveDown = cc.EaseIn:create(cc.MoveTo:create(0.2, cc.p(oldPos.x, oldPos.y - 20)), 0.8);
    local moveBack = cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y));
    CT:runAction(cc.Sequence:create(moveDown, moveBack));
end

-- CT从中心弹出
function ctPopUpFromCenter(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldScale = CT:getScale();

    -- CT从中心弹出
    CT:setScale(oldScale * 0.8);
    local scaleUp1 = cc.EaseIn:create(cc.ScaleTo:create(0.2, oldScale * 1.05), 0.4);
    local scaleUp2 = cc.ScaleTo:create(0.05, oldScale);
    CT:runAction(cc.Sequence:create(scaleUp1, scaleUp2));
end

-- CT节点往上收
function ctMoveUp(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldPos = cc.p(CT:getPosition());
    local moveUp1 = cc.EaseIn:create(cc.MoveTo:create(0.2, cc.p(oldPos.x, DESIGN_HEIGHT)), 0.8);
    CT:runAction(cc.Sequence:create(moveUp1, form.disappearCallFunc));
end

-- CT快速放大并渐隐
function ctScaleUpAndHide(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldScale = CT:getScale();
    local scaleUp = cc.ScaleTo:create(0.15, 1.2 * oldScale);
    local fadeOut = cc.FadeOut:create(0.15);
    CT:runAction(cc.Sequence:create(cc.Spawn:create(scaleUp, fadeOut), form.disappearCallFunc));
end

-- CT从右边飞入
function ctFlyInFromRight(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldPos = cc.p(CT:getPosition());

    -- CT节点从右边飞入，并略微回弹下
    CT:setPosition(DESIGN_WIDTH, oldPos.y);
    local moveIn = cc.EaseIn:create(cc.MoveTo:create(0.35, cc.p(oldPos.x - 20, oldPos.y)), 1.8);
    local moveBack = cc.MoveTo:create(0.15, cc.p(oldPos.x, oldPos.y));
    CT:runAction(cc.Sequence:create(moveIn, moveBack));
end

-- BT从左边飞入
function btFlyInFromLeft(form)
    local BT = findChildByName(form.node, "BT");
    if not BT then
        return;
    end

    if not BT.initPosition then
        BT.initPosition = cc.p(BT:getPosition());
    end

    local oldPos = cc.p(BT:getPosition());

    -- BT节点从左边边飞入，并略微回弹下
    BT:setPosition(-DESIGN_WIDTH, oldPos.y);
    local moveIn = cc.EaseIn:create(cc.MoveTo:create(0.35, cc.p(oldPos.x + 20, oldPos.y)), 1.8);
    local moveBack = cc.MoveTo:create(0.15, cc.p(oldPos.x, oldPos.y));
    BT:runAction(cc.Sequence:create(moveIn, moveBack));
end

-- BOTTOM/BT从左边飞入（阶梯状）
function btFlyInFromLeftDif(form)
    local BT = findChildByName(form.node, "BT");
    local BOTTOM = findChildByName(form.node, "BOTTOM");
    if not BT or not BOTTOM then
        return;
    end

    if not BT.initPosition then
        BT.initPosition = cc.p(BT:getPosition());
    end

    if not BOTTOM.initPosition then
        BOTTOM.initPosition = cc.p(BOTTOM:getPosition());
    end

    local oldPos1 = cc.p(BOTTOM:getPosition());

    -- BOTTOM节点从左边边飞入，并略微回弹下
    BOTTOM:setPosition(-DESIGN_WIDTH, oldPos1.y);
    local moveIn = cc.EaseIn:create(cc.MoveTo:create(0.35, cc.p(oldPos1.x + 20, oldPos1.y)), 1.8);
    local moveBack = cc.MoveTo:create(0.15, cc.p(oldPos1.x, oldPos1.y));
    BOTTOM:runAction(cc.Sequence:create(moveIn, moveBack));

    local oldPos2 = cc.p(BT:getPosition());
    -- BT节点从左边边飞入，并略微回弹下
    BT:setPosition(-DESIGN_WIDTH, oldPos2.y);
    local moveIn2 = cc.EaseIn:create(cc.MoveTo:create(0.35, cc.p(oldPos2.x + 20, oldPos2.y)), 1.8);
    local moveBack2 = cc.MoveTo:create(0.15, cc.p(oldPos2.x, oldPos2.y));
    local delay = cc.DelayTime:create(0.2);
    BT:runAction(cc.Sequence:create(delay, moveIn2, moveBack2));
end

-- CT从右边飞出
function ctFlyOutFromRight(form)
    local CT = findChildByName(form.node, "CT");
    if not CT then
        return;
    end

    local oldPos = cc.p(CT:getPosition());
    local moveOut = cc.EaseIn:create(cc.MoveTo:create(0.2, cc.p(DESIGN_WIDTH, oldPos.y)), 1.8);
    CT:runAction(cc.Sequence:create(moveOut, form.disappearCallFunc));
end

-- BT从左边飞出
function btFlyOutFromLeft(form)
    local BT = findChildByName(form.node, "BT");
    if not BT then
        return;
    end

    if not BT.initPosition then
        BT.initPosition = cc.p(BT:getPosition());
    end

    local oldPos = cc.p(BT:getPosition());
    local moveOut = cc.EaseIn:create(cc.MoveTo:create(0.2, cc.p(-DESIGN_WIDTH, oldPos.y)), 1.8);
    local moveOut2 = cc.EaseIn:create(cc.MoveTo:create(0.2, cc.p(-DESIGN_WIDTH, oldPos.y)), 1.8);
    BT:runAction(cc.Sequence:create(moveOut, form.disappearCallFunc));

   local BOTTOM = findChildByName(form.node, "BOTTOM");
   if BOTTOM then
       -- 有BOTTOM则也需要飞出
       BOTTOM:runAction(cc.Sequence:create(moveOut2));
   end
end

-- BT往下收
function btMoveDown(form)
    local BT = findChildByName(form.node, "BT");
    if not BT then
        return;
    end

    if not BT.initPosition then
        BT.initPosition = cc.p(BT:getPosition());
    end

    local oldPos2 = cc.p(BT:getPosition());
    local moveUp2 = cc.EaseIn:create(cc.MoveTo:create(0.4, cc.p(BT:getPositionX(), -300)), 0.8);
    BT:runAction(moveUp2);
end

-- BT节点一段时间后，从底部往上弹出
function btPopUpFromBottom(form, callback)
    local BT = findChildByName(form.node, "BT");
    if not BT then
        return;
    end

    if not BT.initPosition then
        BT.initPosition = cc.p(BT:getPosition());
    end

    local oldPos = BT.initPosition;
    BT:setPosition(oldPos.x, oldPos.y - 300);
    local delay = cc.DelayTime:create(0.25);
    local moveUp = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y + 5)), 0.3);
    local moveDown = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y - 3)), 0.3);
    local moveUp2 = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y)), 0.3);
    BT:stopAllActions();

    local gotoNextState = cc.CallFunc:create(function ()
        if callback ~= nil then
            callback();
        end
    end);

    BT:runAction(cc.Sequence:create(delay, moveUp ,moveDown, moveUp2, gotoNextState));
end

-- bg渐隐
function bgFadeOut(form)
    local bg = findChildByName(form.node, "bg/bgImg");
    if not bg then
        return;
    end

    bg:runAction(cc.FadeOut:create(0.2));
end

-- BOTTOM节点一段时间后，从底部往上弹出
function bottomPopUpFromBottom(form)
    local BT = findChildByName(form.node, "BOTTOM");
    if not BT then
        return;
    end

    local oldPos;
    if not BT.oldPos then
        oldPos = cc.p(BT:getPosition());
        BT.oldPos = oldPos;
    else
        oldPos = BT.oldPos;
    end

    BT:setPosition(oldPos.x, - 300);
    local delay = cc.DelayTime:create(0.25);
    local moveUp = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y + 5)), 0.3);
    local moveDown = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y - 3)), 0.3);
    local moveUp2 = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPos.x, oldPos.y)), 0.3);
    BT:stopAllActions();
    BT:runAction(cc.Sequence:create(delay, moveUp ,moveDown, moveUp2));
end

-- 如果失去/获得焦点效果的是列表中的界面，那么不需要播放特效
local withOutFocusEffectForms = { "UISkyCity", "UIHeroMain", "UIMercenaryCamp", "UITalentMain", "UIDungeonMain",
    "UIPetRecruitMain", "UIPetRecruit", "UIMopUp", "UICommunicating", "UILoadingEffect", "UINewWorkshop", "UICombatStat"};

-- 播放界面失去焦点的效果
function runLoseFocusEffect(form)
    -- release流先屏蔽
    do return; end

    if table.indexOf(withOutFocusEffectForms, form:getName() or "") > 0 then
        return;
    end

    -- 失去焦点的窗口BT向下移动隐藏起来
    btMoveDown(form);
end

-- 播放界面获得焦点的效果
function runGetFocusEffect(form)
    -- release流先屏蔽
    do return; end

    if table.indexOf(withOutFocusEffectForms, form:getName() or "") > 0 then
        return;
    end

    -- 获得焦点的窗口，BT从下弹出
    btPopUpFromBottom(form);
end
